home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_02_08
/
2n08007b
< prev
next >
Wrap
Text File
|
1991-06-17
|
20KB
|
567 lines
/*
A CUA compliant window class for data entry.
Uses dialog templates created with the resource compiler (rc),
or the OS/2 SDK screen painter (dlgbox).
NB: Unlike a dialog box, a form has a true client window which
owns the data entry control windows.
*/
#include <stdlib.h> /* for calloc() and free() */
#define INCL_DOSRESOURCES /* For DosGetResource() */
#define INCL_WIN
#include <os2.h>
#include "form.h"
extern HAB hab; /* Under OS/2 1.2 you could use
WinQueryAnchorBlock( HWND ) */
static MRESULT EXPENTRY wpFormFrame( HWND, USHORT, MPARAM, MPARAM );
HWND EXPENTRY FormLoad( HWND hwndParent, HWND hwndOwner, PFNWP pfnwp,
HMODULE hmod, USHORT id, PVOID p )
{
SEL sel;
HWND hwnd = NULL;
if (!DosGetResource( hmod, RT_DIALOG, id, &sel ))
{
hwnd = FormCreate( hwndParent, hwndOwner, pfnwp,
MAKEP( sel, 0 ), hmod, id, p );
DosFreeSeg( sel );
}
return hwnd;
}
#define LINE_SIZE 8 /* Number of pels to move on scroll by line */
#define BORDER_SIZE 4 /* Whitespace to be left round edges of form */
#define QWS_CXFORM (2*sizeof(PVOID))
#define QWS_CYFORM (2*sizeof(PVOID)+sizeof(USHORT))
static void set_scrollbars( HWND hwnd,
SHORT cxClient, SHORT cyClient );
HWND EXPENTRY FormCreate( HWND hwndParent, HWND hwndOwner,
PFNWP pfnwp, PDLGTEMPLATE pDlgTemplate,
HMODULE hmod, USHORT id, PVOID p )
{
static BOOL fInitialized;
USHORT i;
HWND hwndFrame, hwnd;
HWND hctl=NULL; /* default control to start with focus */
FRAMECDATA fcdata; /* holds parameters used
to create a frame window */
PSZ pszTitle;
HWND *pahwnd; /* pointer to array of control window handles */
POINTL aptl[2];
DLGTITEM *pDlgItem = &pDlgTemplate->adlgti[ 0 ];
USHORT cxClient, cyClient;
RECTL rclForm;
if (!fInitialized)
{
fInitialized = TRUE;
#define CLASS_NAME "FORM" /* any unique name will do */
WinRegisterClass( hab, CLASS_NAME, wpForm, 0,
2*sizeof(PVOID)+2*sizeof(USHORT) );
}
fcdata.cb = sizeof fcdata; /* initialization required by PM */
fcdata.flCreateFlags =
*(PULONG)((PBYTE)pDlgTemplate +
pDlgTemplate->adlgti[0].offCtlData)|
FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER |
FCF_HORZSCROLL | FCF_VERTSCROLL;
fcdata.hmodResources = hmod;
fcdata.idResources = id;
pszTitle = (PSZ)pDlgTemplate + pDlgTemplate->adlgti[ 0 ].offText;
if (!*pszTitle) /* if no text for title bar */
pszTitle = "(Untitled)"; /* provide something */
aptl[0].x = pDlgItem->x; /* read size and position of form */
aptl[0].y = pDlgItem->y; /* from first DLGTITEM structure */
aptl[1].x = pDlgItem->cx;
aptl[1].y = pDlgItem->cy;
/* convert from dialog units to pels */
WinMapDlgPoints( hwndParent, aptl, 2, TRUE );
cxClient = (USHORT)aptl[1].x;
cyClient = (USHORT)aptl[1].y;
/* inflate the frame window to accomodate controls around the form */
aptl[0].x -= WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER );
aptl[0].y -= WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER );
aptl[0].y -= WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL );
aptl[1].x += 2 * WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER );
aptl[1].x += WinQuerySysValue( HWND_DESKTOP, SV_CXVSCROLL );
aptl[1].y += 2 * WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER );
aptl[1].y += WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR );
aptl[1].y += WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL );
if (fcdata.flCreateFlags & FCF_MENU)
aptl[1].y += WinQuerySysValue( HWND_DESKTOP, SV_CYMENU );
hwndFrame = WinCreateWindow( hwndParent, WC_FRAME, pszTitle,
0, 0, 0, 0, 0, hwndOwner, HWND_TOP, id,
&fcdata, 0 );
if (!hwndFrame)
{
/* display PM error message */
ErrorInfoMessageBox( hab, hwndParent, "Form creation error" );
return NULL;
}
hwnd = WinCreateWindow( hwndFrame, CLASS_NAME, 0, 0, 0, 0, 0, 0, 0,
HWND_TOP, FID_CLIENT, 0, 0 );
WinSetWindowPos( hwndFrame, HWND_TOP,
(SHORT)aptl[0].x, (SHORT)aptl[0].y,
(SHORT)aptl[1].x, (SHORT)aptl[1].y,
SWP_SIZE | SWP_MOVE );
pahwnd = (HWND*)calloc( pDlgTemplate->adlgti[ 0 ].cChildren+1,
sizeof(HWND) );
WinSetWindowPtr( hwnd, QWL_USER+sizeof(PVOID), pahwnd );
rclForm.xLeft = rclForm.xRight =
rclForm.yBottom = rclForm.yTop = 0;
/* create the child control windows */
for (i = 1; i <= pDlgTemplate->adlgti[ 0 ].cChildren; i++)
{
pDlgItem = &pDlgTemplate->adlgti[ i ];
aptl[0].x = pDlgItem->x;
aptl[0].y = pDlgItem->y;
aptl[1].x = pDlgItem->cx;
aptl[1].y = pDlgItem->cy;
WinMapDlgPoints( hwnd, aptl, 2, TRUE/*Convert du to pels*/ );
pahwnd[ i-1 ] = WinCreateWindow( hwnd,
pDlgItem->offClassName < 10 ?
/* Stock class or user defined? */
(PSZ)(0xFFFF0000 | (LONG)pDlgItem->offClassName):
(PSZ)pDlgTemplate + pDlgItem->offClassName,
(PSZ)pDlgTemplate + pDlgItem->offText,
pDlgItem->flStyle,
(SHORT)aptl[0].x, (SHORT)aptl[0].y,
(SHORT)aptl[1].x, (SHORT)aptl[1].y, hwnd, HWND_TOP,
pDlgItem->id, 0, 0 );
/* record first tabstop item - will receive default focus */
if (!hctl && pDlgItem->flStyle & WS_TABSTOP)
hctl = pahwnd[ i-1 ];
rclForm.xLeft = min( rclForm.xLeft, aptl[0].x );
rclForm.yBottom = min( rclForm.yBottom, aptl[0].y );
rclForm.xRight = max( rclForm.xRight, aptl[0].x+aptl[1].x );
rclForm.yTop = max( rclForm.yTop, aptl[0].y+aptl[1].y );
}
WinSetWindowUShort( hwnd, QWS_CXFORM,
(USHORT)(rclForm.xRight-rclForm.xLeft+
2*BORDER_SIZE) );
WinSetWindowUShort( hwnd, QWS_CYFORM,
(USHORT)(rclForm.yTop-rclForm.yBottom+
2*BORDER_SIZE) );
WinSubclassWindow( hwndFrame, wpFormFrame );/* for scrollbars */
WinSubclassWindow( hwnd, pfnwp/*user defined window proc*/ );
set_scrollbars( hwnd, cxClient, cyClient );
if (!WinSendMsg( hwnd, WM_INITDLG, hctl, p ))
WinSetFocus( HWND_DESKTOP, hctl );
if (pDlgItem->flStyle & WS_VISIBLE)
WinShowWindow( hwndFrame, TRUE );
return hwnd;
}
static MRESULT EXPENTRY wpFormFrame( HWND hwnd, USHORT msg,
MPARAM mp1, MPARAM mp2 )
{
USHORT usPos, usMin, usMax;
SHORT sMove;
HWND hctl;
MRESULT mr;
RECTL rclUpdate;
switch( msg )
{
case WM_HSCROLL:
case WM_VSCROLL:
hctl = WinWindowFromID( hwnd, SHORT1FROMMP(mp1) );
mr = WinSendMsg( hctl, SBM_QUERYRANGE, 0L, 0L );
usMin = SHORT1FROMMR( mr );
usMax = SHORT2FROMMR( mr );
usPos = SHORT1FROMMR( WinSendMsg( hctl, SBM_QUERYPOS, 0L, 0L ) );
#if !defined(min)
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
switch (SHORT2FROMMP(mp2))
{
case SB_LINELEFT: /* #defined same as SB_LINEUP */
sMove = -min( LINE_SIZE, usPos-usMin );
break;
case SB_PAGELEFT: /* #defined same as SB_PAGEUP */
sMove = -min( 8*LINE_SIZE, usPos-usMin );
break;
case SB_LINERIGHT:/* #defined same as SB_LINEDOWN */
sMove = +min( LINE_SIZE, usMax-usPos );
break;
case SB_PAGERIGHT:/* #defined same as SB_PAGEDOWN */